// Licensed to Elasticsearch B.V under one or more agreements.
// Elasticsearch B.V licenses this file to you under the Apache 2.0 License.
// See the LICENSE file in the project root for more information.
//
// ███╗   ██╗ ██████╗ ████████╗██╗ ██████╗███████╗
// ████╗  ██║██╔═══██╗╚══██╔══╝██║██╔════╝██╔════╝
// ██╔██╗ ██║██║   ██║   ██║   ██║██║     █████╗
// ██║╚██╗██║██║   ██║   ██║   ██║██║     ██╔══╝
// ██║ ╚████║╚██████╔╝   ██║   ██║╚██████╗███████╗
// ╚═╝  ╚═══╝ ╚═════╝    ╚═╝   ╚═╝ ╚═════╝╚══════╝
// ------------------------------------------------
//
// This file is automatically generated.
// Please do not edit these files manually.
//
// ------------------------------------------------

#nullable restore

using Elastic.Clients.Elasticsearch.Serverless.Fluent;
using Elastic.Clients.Elasticsearch.Serverless.Serialization;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Elastic.Clients.Elasticsearch.Serverless.Mapping;

public sealed partial class RuntimeField
{
	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("fetch_fields")]
	public ICollection<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFields>? FetchFields { get; set; }

	/// <summary>
	/// <para>A custom format for `date` type runtime fields.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("format")]
	public string? Format { get; set; }

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("input_field")]
	public Elastic.Clients.Elasticsearch.Serverless.Field? InputField { get; set; }

	/// <summary>
	/// <para>Painless script executed at query time.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("script")]
	public Elastic.Clients.Elasticsearch.Serverless.Script? Script { get; set; }

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("target_field")]
	public Elastic.Clients.Elasticsearch.Serverless.Field? TargetField { get; set; }

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("target_index")]
	public Elastic.Clients.Elasticsearch.Serverless.IndexName? TargetIndex { get; set; }

	/// <summary>
	/// <para>Field type, which can be: `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`,`keyword`, `long`, or `lookup`.</para>
	/// </summary>
	[JsonInclude, JsonPropertyName("type")]
	public Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldType Type { get; set; }
}

public sealed partial class RuntimeFieldDescriptor<TDocument> : SerializableDescriptor<RuntimeFieldDescriptor<TDocument>>
{
	internal RuntimeFieldDescriptor(Action<RuntimeFieldDescriptor<TDocument>> configure) => configure.Invoke(this);

	public RuntimeFieldDescriptor() : base()
	{
	}

	private ICollection<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFields>? FetchFieldsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument> FetchFieldsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>> FetchFieldsDescriptorAction { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>>[] FetchFieldsDescriptorActions { get; set; }
	private string? FormatValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field? InputFieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Script? ScriptValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field? TargetFieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexName? TargetIndexValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldType TypeValue { get; set; }

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> FetchFields(ICollection<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFields>? fetchFields)
	{
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsValue = fetchFields;
		return Self;
	}

	public RuntimeFieldDescriptor<TDocument> FetchFields(Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument> descriptor)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsDescriptor = descriptor;
		return Self;
	}

	public RuntimeFieldDescriptor<TDocument> FetchFields(Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>> configure)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsDescriptorAction = configure;
		return Self;
	}

	public RuntimeFieldDescriptor<TDocument> FetchFields(params Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>>[] configure)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = configure;
		return Self;
	}

	/// <summary>
	/// <para>A custom format for `date` type runtime fields.</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> Format(string? format)
	{
		FormatValue = format;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> InputField(Elastic.Clients.Elasticsearch.Serverless.Field? inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> InputField<TValue>(Expression<Func<TDocument, TValue>> inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> InputField(Expression<Func<TDocument, object>> inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>Painless script executed at query time.</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> Script(Elastic.Clients.Elasticsearch.Serverless.Script? script)
	{
		ScriptValue = script;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> TargetField(Elastic.Clients.Elasticsearch.Serverless.Field? targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> TargetField<TValue>(Expression<Func<TDocument, TValue>> targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> TargetField(Expression<Func<TDocument, object>> targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> TargetIndex(Elastic.Clients.Elasticsearch.Serverless.IndexName? targetIndex)
	{
		TargetIndexValue = targetIndex;
		return Self;
	}

	/// <summary>
	/// <para>Field type, which can be: `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`,`keyword`, `long`, or `lookup`.</para>
	/// </summary>
	public RuntimeFieldDescriptor<TDocument> Type(Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldType type)
	{
		TypeValue = type;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (FetchFieldsDescriptor is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, FetchFieldsDescriptor, options);
			writer.WriteEndArray();
		}
		else if (FetchFieldsDescriptorAction is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>(FetchFieldsDescriptorAction), options);
			writer.WriteEndArray();
		}
		else if (FetchFieldsDescriptorActions is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			foreach (var action in FetchFieldsDescriptorActions)
			{
				JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor<TDocument>(action), options);
			}

			writer.WriteEndArray();
		}
		else if (FetchFieldsValue is not null)
		{
			writer.WritePropertyName("fetch_fields");
			JsonSerializer.Serialize(writer, FetchFieldsValue, options);
		}

		if (!string.IsNullOrEmpty(FormatValue))
		{
			writer.WritePropertyName("format");
			writer.WriteStringValue(FormatValue);
		}

		if (InputFieldValue is not null)
		{
			writer.WritePropertyName("input_field");
			JsonSerializer.Serialize(writer, InputFieldValue, options);
		}

		if (ScriptValue is not null)
		{
			writer.WritePropertyName("script");
			JsonSerializer.Serialize(writer, ScriptValue, options);
		}

		if (TargetFieldValue is not null)
		{
			writer.WritePropertyName("target_field");
			JsonSerializer.Serialize(writer, TargetFieldValue, options);
		}

		if (TargetIndexValue is not null)
		{
			writer.WritePropertyName("target_index");
			JsonSerializer.Serialize(writer, TargetIndexValue, options);
		}

		writer.WritePropertyName("type");
		JsonSerializer.Serialize(writer, TypeValue, options);
		writer.WriteEndObject();
	}
}

public sealed partial class RuntimeFieldDescriptor : SerializableDescriptor<RuntimeFieldDescriptor>
{
	internal RuntimeFieldDescriptor(Action<RuntimeFieldDescriptor> configure) => configure.Invoke(this);

	public RuntimeFieldDescriptor() : base()
	{
	}

	private ICollection<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFields>? FetchFieldsValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor FetchFieldsDescriptor { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor> FetchFieldsDescriptorAction { get; set; }
	private Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor>[] FetchFieldsDescriptorActions { get; set; }
	private string? FormatValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field? InputFieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Script? ScriptValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Field? TargetFieldValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.IndexName? TargetIndexValue { get; set; }
	private Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldType TypeValue { get; set; }

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor FetchFields(ICollection<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFields>? fetchFields)
	{
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsValue = fetchFields;
		return Self;
	}

	public RuntimeFieldDescriptor FetchFields(Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor descriptor)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsDescriptor = descriptor;
		return Self;
	}

	public RuntimeFieldDescriptor FetchFields(Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor> configure)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorActions = null;
		FetchFieldsDescriptorAction = configure;
		return Self;
	}

	public RuntimeFieldDescriptor FetchFields(params Action<Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor>[] configure)
	{
		FetchFieldsValue = null;
		FetchFieldsDescriptor = null;
		FetchFieldsDescriptorAction = null;
		FetchFieldsDescriptorActions = configure;
		return Self;
	}

	/// <summary>
	/// <para>A custom format for `date` type runtime fields.</para>
	/// </summary>
	public RuntimeFieldDescriptor Format(string? format)
	{
		FormatValue = format;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor InputField(Elastic.Clients.Elasticsearch.Serverless.Field? inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor InputField<TDocument, TValue>(Expression<Func<TDocument, TValue>> inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor InputField<TDocument>(Expression<Func<TDocument, object>> inputField)
	{
		InputFieldValue = inputField;
		return Self;
	}

	/// <summary>
	/// <para>Painless script executed at query time.</para>
	/// </summary>
	public RuntimeFieldDescriptor Script(Elastic.Clients.Elasticsearch.Serverless.Script? script)
	{
		ScriptValue = script;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor TargetField(Elastic.Clients.Elasticsearch.Serverless.Field? targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor TargetField<TDocument, TValue>(Expression<Func<TDocument, TValue>> targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor TargetField<TDocument>(Expression<Func<TDocument, object>> targetField)
	{
		TargetFieldValue = targetField;
		return Self;
	}

	/// <summary>
	/// <para>For type `lookup`</para>
	/// </summary>
	public RuntimeFieldDescriptor TargetIndex(Elastic.Clients.Elasticsearch.Serverless.IndexName? targetIndex)
	{
		TargetIndexValue = targetIndex;
		return Self;
	}

	/// <summary>
	/// <para>Field type, which can be: `boolean`, `composite`, `date`, `double`, `geo_point`, `ip`,`keyword`, `long`, or `lookup`.</para>
	/// </summary>
	public RuntimeFieldDescriptor Type(Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldType type)
	{
		TypeValue = type;
		return Self;
	}

	protected override void Serialize(Utf8JsonWriter writer, JsonSerializerOptions options, IElasticsearchClientSettings settings)
	{
		writer.WriteStartObject();
		if (FetchFieldsDescriptor is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, FetchFieldsDescriptor, options);
			writer.WriteEndArray();
		}
		else if (FetchFieldsDescriptorAction is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor(FetchFieldsDescriptorAction), options);
			writer.WriteEndArray();
		}
		else if (FetchFieldsDescriptorActions is not null)
		{
			writer.WritePropertyName("fetch_fields");
			writer.WriteStartArray();
			foreach (var action in FetchFieldsDescriptorActions)
			{
				JsonSerializer.Serialize(writer, new Elastic.Clients.Elasticsearch.Serverless.Mapping.RuntimeFieldFetchFieldsDescriptor(action), options);
			}

			writer.WriteEndArray();
		}
		else if (FetchFieldsValue is not null)
		{
			writer.WritePropertyName("fetch_fields");
			JsonSerializer.Serialize(writer, FetchFieldsValue, options);
		}

		if (!string.IsNullOrEmpty(FormatValue))
		{
			writer.WritePropertyName("format");
			writer.WriteStringValue(FormatValue);
		}

		if (InputFieldValue is not null)
		{
			writer.WritePropertyName("input_field");
			JsonSerializer.Serialize(writer, InputFieldValue, options);
		}

		if (ScriptValue is not null)
		{
			writer.WritePropertyName("script");
			JsonSerializer.Serialize(writer, ScriptValue, options);
		}

		if (TargetFieldValue is not null)
		{
			writer.WritePropertyName("target_field");
			JsonSerializer.Serialize(writer, TargetFieldValue, options);
		}

		if (TargetIndexValue is not null)
		{
			writer.WritePropertyName("target_index");
			JsonSerializer.Serialize(writer, TargetIndexValue, options);
		}

		writer.WritePropertyName("type");
		JsonSerializer.Serialize(writer, TypeValue, options);
		writer.WriteEndObject();
	}
}